﻿using System;
using System.Collections.Generic;
using System.Linq;
using NUnit.Framework;

namespace CSSpec
{
    public static class NUnitExtensions
    {
        public static void ShouldEqual<T>(this T source, T expected)
        {
            Assert.AreEqual(expected, source);
        }
        public static void ShouldEqual(this object source, object expected)
        {
            Assert.AreEqual(expected, source);
        }
        public static void ShouldEqualOne<T>(this T number)
        {
            Assert.AreEqual(number, 1);
        }
        public static void ShouldEqualZero<T>(this T number)
        {
            Assert.AreEqual(number, 0);
        }
        public static void ShouldNotEqual<T>(this T source, T expected)
        {
            Assert.AreNotEqual(expected, source);
        }
        public static void ShouldBeTrue(this bool condition)
        {
            Assert.IsTrue(condition);
        }
        public static void ShouldBeFalse(this bool condition)
        {
            Assert.IsFalse(condition);
        }
        public static void ShouldHaveNullProperty<T>(this T source, Func<T, object> property)
        {
            Assert.IsNull(property(source));
        }
        public static void ShouldNotHaveNullProperty<T>(this T source, Func<T, object> property)
        {
            Assert.IsNotNull(property(source));
        } 
        public static void ShouldBeOfType<T>(this T source, Type expectedType)
        {
            Assert.AreEqual(expectedType, source.GetType());
        }
        public static void ShouldHaveTheSameReferenceAs<T>(this T source, T other)
        {
            Assert.AreSame(source, other);
        } 
        public static void ShouldBeGreaterThan(this IComparable source, IComparable other)
        {
            Assert.Greater(source, other);
        } 
        public static void ShouldBeLessThan(this IComparable source, IComparable other)
        {
            Assert.Less(source, other);
        }
        public static void ShouldNotBeNull<T>(this T source)
        {
            Assert.IsNotNull(source);
        }
        public static void ShouldBeNull<T>(this T source)
        {
            Assert.IsNull(source);
        } 
        public static T ShouldHaveOneItem<T>(this IEnumerable<T> collection)
        {
            Assert.AreEqual(1, collection.Count());
            return collection.Single();
        }
        public static T ShouldHaveOneItemWhere<T>(this IEnumerable<T> collection, Func<T, bool> condition)
        {
            Assert.AreEqual(1, collection.Count(condition));
            return collection.Single(condition);
        }
        public static void ShouldHaveAtLeastOneItem<T>(this IEnumerable<T> collection)
        {
            Assert.Greater(collection.Count(), 0);
        }
        public static void ShouldHaveCount<T>(this IEnumerable<T> collection, int expectedCount)
        {
            Assert.AreEqual(expectedCount, collection.Count());
        } 
        public static void ShouldHaveCountWhere<T>(this IEnumerable<T> collection, int count, Func<T, bool> condition)
        {
            Assert.AreEqual(count, collection.Count(condition));
        }   
        public static void ShouldContain(this string source, string expected)
        {
            Assert.IsTrue(source.Contains(expected));
        }
    }
}
